/**
 * Created by xuyq on 2023/3/6.
 */
const Nightmare = require('nightmare');

const nightmare = Nightmare({
    waitTimeout: 60 * 1000 * 2,
    show: true,
    openDevTools: {
        mode: 'detach'
    },
});

const visitedUrls = new Set();

const result = [];
let pageData = []
const crawlPage = async (url) => {
    if (visitedUrls.has(url) ) {
        return;
    }
    visitedUrls.add(url);
    console.log(`Crawling ${url}...`);
    try {
        const page = nightmare.goto(url);
        const pageTitle = await page.title();
        result.push({url, pageTitle});
        await page.wait(2000)
        await page.inject('js', 'node_modules/jquery/dist/jquery.min.js')
        const {links, data} = await page.evaluate(() => {
            const contentSelectorKey = '.crawler_content'
            const activeSelectorKey = 'a.crawler_active'
            const levelClassReg = /(lv)\d/

            const actives = Array.from(document.querySelectorAll(activeSelectorKey)).sort((a,b)=>{
                let a_class = a.classList.value.match(levelClassReg) && a.classList.value.match(levelClassReg)[0] || 'lv5'
                let b_class = b.classList.value.match(levelClassReg) && b.classList.value.match(levelClassReg)[0] || 'lv5'
                return a_class.split('lv')[1] - b_class.split('lv')[1]
            }).map(function (el) {
                return el.innerText || el.textContent
            })
            const contents = Array.from(document.querySelectorAll(contentSelectorKey)).filter(function (el) {
                const {width, height} = el.getBoundingClientRect();
                const level = el.classList.value.match(levelClassReg) && el.classList.value.match(levelClassReg)[0].split('lv')[1] || '5'
                return width && height && level >= actives[actives.length - 1]
            })
            const data = contents.map(el => {
                return {
                    url: window.location.href,
                    content: el.innerText || el.textContent,
                    path: actives.length ? actives.join('/').replace(/\n/g, '') : '',
                }
            })


            const linkNodes = document.querySelectorAll('a.crawler');
            const links = [];
            linkNodes.forEach((node) => {
                if (!node.href.baseVal)
                    links.push(node.href)
                else {
                    const link = `${window.location.href.split('#')[0]}${node.href.baseVal}`
                    links.push(link)
                }
            });
            return {links, data};
        });
        pageData = pageData.concat(data)
        for (let link of links) {
            await crawlPage(link);
        }
    } catch (error) {
        console.error(`Failed to crawl ${url}: ${error}`);
    }
};


nightmare.goto('http://localhost:8080/#/login?redirect=aHR0cDovL2xvY2FsaG9zdDo4MDgwLyMvaG9tZQ%3D%3D')
    .type('input[placeholder="用户名"]', 'yanqi.xu')
    .type('input[placeholder="密码"]', '123123123')
    .click('button')
    .wait('.banner')
    .inject('js', 'node_modules/jquery/dist/jquery.min.js')
    .url()
    .then(async url => {
        await crawlPage(url)
        console.log(pageData);
        nightmare.end();
    })
    .catch((error) => {
        console.error('Search failed:', error);
        nightmare.end();
    });
// nightmare.goto('http://localhost:8080/#/framework').title().wait(2000)

// crawlPage(url)
//     .then(() => {
//         console.log(result);
//         nightmare.end();
//     })
//     .catch((error) => {
//         console.error('Search failed:', error);
//         nightmare.end();
//     });



